package com.ljy.farm.service.MaterialExtend;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.ljy.farm.constants.BusinessConstants;
import com.ljy.farm.datasource.entities.MaterialExtend;
import com.ljy.farm.datasource.entities.MaterialExtendExample;
import com.ljy.farm.datasource.entities.User;
import com.ljy.farm.datasource.mappers.MaterialExtendMapper;
import com.ljy.farm.datasource.mappers.MaterialExtendMapperEx;
import com.ljy.farm.datasource.vo.MaterialExtendVo4List;
import com.ljy.farm.exception.JshException;
import com.ljy.farm.service.log.LogService;
import com.ljy.farm.service.user.UserService;
import com.ljy.farm.utils.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;


@Service
public class MaterialExtendService {
    private Logger logger = LoggerFactory.getLogger(MaterialExtendService.class);

    @Resource
    private MaterialExtendMapper materialExtendMapper;
    @Resource
    private MaterialExtendMapperEx materialExtendMapperEx;
    @Resource
    private LogService logService;
    @Resource
    private UserService userService;

    public MaterialExtend getMaterialExtend(long id) throws Exception {
        MaterialExtend result = null;
        try {
            result = materialExtendMapper.selectByPrimaryKey(id);
        } catch (Exception e) {
            JshException.readFail(logger, e);
        }
        return result;
    }

    public List<MaterialExtendVo4List> getDetailList(Long materialId) {
        List<MaterialExtendVo4List> list = null;
        try {
            list = materialExtendMapperEx.getDetailList(materialId);
        } catch (Exception e) {
            JshException.readFail(logger, e);
        }
        return list;
    }

    public List<MaterialExtend> getListByMIds(List<Long> idList) {
        List<MaterialExtend> meList = null;
        try {
            Long[] idArray = StringUtil.listToLongArray(idList);
            if (idArray != null && idArray.length > 0) {
                meList = materialExtendMapperEx.getListByMId(idArray);
            }
        } catch (Exception e) {
            JshException.readFail(logger, e);
        }
        return meList;
    }

    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
    public String saveDetials(String inserted, String deleted, String updated, Long materialId) throws Exception {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        logService.insertLog("商品价格扩展",
                BusinessConstants.LOG_OPERATION_TYPE_ADD, request);
        //转为json
        JSONArray insertedJson = JSONArray.parseArray(inserted);
        JSONArray deletedJson = JSONArray.parseArray(deleted);
        JSONArray updatedJson = JSONArray.parseArray(updated);
        if (null != insertedJson) {
            for (int i = 0; i < insertedJson.size(); i++) {
                MaterialExtend materialExtend = new MaterialExtend();
                JSONObject tempInsertedJson = JSONObject.parseObject(insertedJson.getString(i));
                materialExtend.setMaterialId(materialId);
                if (StringUtils.isNotEmpty(tempInsertedJson.getString("BarCode"))) {
                    materialExtend.setBarCode(tempInsertedJson.getString("BarCode"));
                }
                if (StringUtils.isNotEmpty(tempInsertedJson.getString("CommodityUnit"))) {
                    materialExtend.setCommodityUnit(tempInsertedJson.getString("CommodityUnit"));
                }
                if (StringUtils.isNotEmpty(tempInsertedJson.getString("PurchaseDecimal"))) {
                    materialExtend.setPurchaseDecimal(tempInsertedJson.getBigDecimal("PurchaseDecimal"));
                }
                if (StringUtils.isNotEmpty(tempInsertedJson.getString("CommodityDecimal"))) {
                    materialExtend.setCommodityDecimal(tempInsertedJson.getBigDecimal("CommodityDecimal"));
                }
                if (StringUtils.isNotEmpty(tempInsertedJson.getString("WholesaleDecimal"))) {
                    materialExtend.setWholesaleDecimal(tempInsertedJson.getBigDecimal("WholesaleDecimal"));
                }
                if (StringUtils.isNotEmpty(tempInsertedJson.getString("LowDecimal"))) {
                    materialExtend.setLowDecimal(tempInsertedJson.getBigDecimal("LowDecimal"));
                }
                if (StringUtil.isEmpty(materialExtend.getBarCode())) {
                    materialExtend.setBarCode(generateUniqueBarcode());
                }
                this.insertMaterialExtend(materialExtend);
            }
        }
        if (!StringUtil.isEmpty(deleted)) {
            JSONArray deletedArray = JSONArray.parseArray(deleted);
            if (deletedArray != null && deletedArray.size() > 0) {
                StringBuffer sb = new StringBuffer();
                for (int i = 0; i < deletedArray.size(); i++) {
                    JSONObject job = deletedArray.getJSONObject(i);
                    sb.append(job.get("id"));
                    if (i < deletedArray.size() - 1) {
                        sb.append(",");
                    }
                }
                if (sb.length() > 0) {
                    this.batchDeleteMaterialExtendByIds(sb.toString(),
                            ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest());
                }
            }
        }
        if (null != updatedJson) {
            for (int i = 0; i < updatedJson.size(); i++) {
                JSONObject tempUpdatedJson = JSONObject.parseObject(updatedJson.getString(i));
                MaterialExtend materialExtend = new MaterialExtend();
                materialExtend.setId(tempUpdatedJson.getLong("Id"));
                if (StringUtils.isNotEmpty(tempUpdatedJson.getString("BarCode"))) {
                    materialExtend.setBarCode(tempUpdatedJson.getString("BarCode"));
                }
                if (StringUtils.isNotEmpty(tempUpdatedJson.getString("CommodityUnit"))) {
                    materialExtend.setCommodityUnit(tempUpdatedJson.getString("CommodityUnit"));
                }
                if (StringUtils.isNotEmpty(tempUpdatedJson.getString("PurchaseDecimal"))) {
                    materialExtend.setPurchaseDecimal(tempUpdatedJson.getBigDecimal("PurchaseDecimal"));
                }
                if (StringUtils.isNotEmpty(tempUpdatedJson.getString("CommodityDecimal"))) {
                    materialExtend.setCommodityDecimal(tempUpdatedJson.getBigDecimal("CommodityDecimal"));
                }
                if (StringUtils.isNotEmpty(tempUpdatedJson.getString("WholesaleDecimal"))) {
                    materialExtend.setWholesaleDecimal(tempUpdatedJson.getBigDecimal("WholesaleDecimal"));
                }
                if (StringUtils.isNotEmpty(tempUpdatedJson.getString("LowDecimal"))) {
                    materialExtend.setLowDecimal(tempUpdatedJson.getBigDecimal("LowDecimal"));
                }
                this.updateMaterialExtend(materialExtend, request);
            }
        }
        return null;
    }

    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
    public int insertMaterialExtend(MaterialExtend materialExtend) throws Exception {
        User user = userService.getCurrentUser();
        materialExtend.setDeleteFlag(BusinessConstants.DELETE_FLAG_EXISTS);
        materialExtend.setCreateTime(new Date());
        materialExtend.setUpdateTime(new Date().getTime());
        materialExtend.setCreateSerial(user.getLoginName());
        materialExtend.setUpdateSerial(user.getLoginName());
        int result = 0;
        try {
            result = materialExtendMapper.insertSelective(materialExtend);
        } catch (Exception e) {
            JshException.writeFail(logger, e);
        }
        return result;
    }

    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
    public int updateMaterialExtend(MaterialExtend MaterialExtend, HttpServletRequest request) throws Exception {
        User user = userService.getCurrentUser();
        MaterialExtend.setUpdateTime(new Date().getTime());
        MaterialExtend.setUpdateSerial(user.getLoginName());
        int res = 0;
        try {
            res = materialExtendMapper.updateByPrimaryKeySelective(MaterialExtend);
        } catch (Exception e) {
            JshException.writeFail(logger, e);
        }
        return res;
    }

    public int checkIsExist(Long id, String MaterialExtendName) throws Exception {
        MaterialExtendExample example = new MaterialExtendExample();
        MaterialExtendExample.Criteria criteria = example.createCriteria();
        criteria.andBarCodeEqualTo(MaterialExtendName);
        if (id > 0) {
            criteria.andIdNotEqualTo(id);
        }
        List<MaterialExtend> list = null;
        try {
            list = materialExtendMapper.selectByExample(example);
        } catch (Exception e) {
            JshException.readFail(logger, e);
        }
        return list == null ? 0 : list.size();
    }

    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
    public int deleteMaterialExtend(Long id, HttpServletRequest request) throws Exception {
        int result = 0;
        MaterialExtend materialExtend = new MaterialExtend();
        materialExtend.setId(id);
        materialExtend.setDeleteFlag(BusinessConstants.DELETE_FLAG_DELETED);
        Object userInfo = request.getSession().getAttribute("user");
        User user = (User) userInfo;
        materialExtend.setUpdateTime(new Date().getTime());
        materialExtend.setUpdateSerial(user.getLoginName());
        try {
            result = materialExtendMapper.updateByPrimaryKeySelective(materialExtend);
        } catch (Exception e) {
            JshException.writeFail(logger, e);
        }
        return result;
    }

    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
    public int batchDeleteMaterialExtendByIds(String ids, HttpServletRequest request) throws Exception {
        logService.insertLog("商品价格扩展",
                new StringBuffer(BusinessConstants.LOG_OPERATION_TYPE_DELETE).append(ids).toString(),
                request);
        String[] idArray = ids.split(",");
        int result = 0;
        try {
            result = materialExtendMapperEx.batchDeleteMaterialExtendByIds(idArray);
        } catch (Exception e) {
            JshException.writeFail(logger, e);
        }
        return result;
    }

    public int insertMaterialExtend(String beanJson, HttpServletRequest request) throws Exception {
        MaterialExtend materialExtend = JSONObject.parseObject(beanJson, MaterialExtend.class);
        int result = 0;
        try {
            result = materialExtendMapper.insertSelective(materialExtend);
        } catch (Exception e) {
            JshException.writeFail(logger, e);
        }
        return result;
    }

    public int updateMaterialExtend(String beanJson, Long id, HttpServletRequest request) throws Exception {
        MaterialExtend materialExtend = JSONObject.parseObject(beanJson, MaterialExtend.class);
        int result = 0;
        try {
            result = materialExtendMapper.insertSelective(materialExtend);
        } catch (Exception e) {
            JshException.writeFail(logger, e);
        }
        return result;
    }

    public List<MaterialExtend> getMaterialExtendByTenantAndTime(Long tenantId, Long lastTime, Long syncNum) throws Exception {
        List<MaterialExtend> list = new ArrayList<MaterialExtend>();
        try {
            //先获取最大的时间戳，再查两个时间戳之间的数据，这样同步能够防止丢失数据（应为时间戳有重复）
            Long maxTime = materialExtendMapperEx.getMaxTimeByTenantAndTime(tenantId, lastTime, syncNum);
            if (tenantId != null && lastTime != null && maxTime != null) {
                MaterialExtendExample example = new MaterialExtendExample();
                example.createCriteria().andTenantIdEqualTo(tenantId)
                        .andUpdateTimeGreaterThan(lastTime)
                        .andUpdateTimeLessThanOrEqualTo(maxTime);
                list = materialExtendMapper.selectByExample(example);
            }
        } catch (Exception e) {
            JshException.readFail(logger, e);
        }
        return list;
    }

    private String generateUniqueBarcode() {
        String barcode;
        do {
            long timeMillis = System.currentTimeMillis();
            long randomSuffix = new Random().nextInt(100);
            barcode = "BC" + timeMillis + randomSuffix;
        } while (materialExtendMapperEx.countByBarCode(barcode) > 0);
        return barcode;
    }
}
